package com.decent.ejfadmin.finance.service.impl;

import com.decent.ejfadmin.collectcard.dao.CollectCardRecordDao;
import com.decent.ejfadmin.common.bean.*;
import com.decent.ejfadmin.common.enums.UserAddMoneyTypeEnum;
import com.decent.ejfadmin.common.exception.OperateFailException;
import com.decent.ejfadmin.finance.dao.SupplyCardDao;
import com.decent.ejfadmin.finance.request.SupplyCardBalanceParam;
import com.decent.ejfadmin.finance.request.SupplyCardDetailParam;
import com.decent.ejfadmin.finance.response.dto.SupplyCardBalanceDto;
import com.decent.ejfadmin.finance.response.dto.SupplyCardDetailDto;
import com.decent.ejfadmin.finance.service.SupplyCardService;
import com.decent.ejfadmin.finance.service.SupplyFinanceService;
import com.decent.ejfadmin.user.dao.UserDao;
import com.decent.ejfadmin.utils.FinanceUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedWriter;
import java.io.OutputStreamWriter;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * @author zhangchao
 * @date 2018/7/28 8:45
 */
@Service
@Slf4j
public class SupplyCardServiceImpl implements SupplyCardService {

    @Autowired
    private SupplyCardDao supplyCardDao;
    @Autowired
    private UserDao userDao;
    @Autowired
    private SupplyFinanceService supplyFinanceService;
    @Autowired
    private FinanceUtils financeUtils;
    @Autowired
    private CollectCardRecordDao collectCardRecordDao;

    /**
     * 查询销卡明细分页数据
     *
     * @param param
     * @return
     */
    @Override
    public Page findSupplyCardDetailPage(SupplyCardDetailParam param) {
        int total = supplyCardDao.querySupplyCardDetailCount(param);
        param.getPageUnit().setTotal(total);
        if (total == 0) {
            param.getPageUnit().setResultList(new ArrayList<>());
        } else {
            List<SupplyCardDetailDto> resultList = supplyCardDao.querySupplyCardDetailPage(param);
            resultList.forEach((bean) -> {
                SupplyProduct product;
                if (bean.getProductId() != null&&bean.getProductId()!=0) {
                    product = collectCardRecordDao.queryProductInfoById(bean.getProductId());
                } else {
                    product = collectCardRecordDao.queryProductInfoByFaceAreaType(bean.getFace(), bean.getArea(), bean.getProductType());
                }
                if (product != null) {
                    bean.setCardOperatorName(product.getCardOperatorName());
                }
            });
            param.getPageUnit().setResultList(resultList);
        }
        return param.getPageUnit();
    }

    /**
     * 查询销卡余额分页数据
     *
     * @param param
     * @return
     */
    @Override
    public Page findSupplyCardBalancePage(SupplyCardBalanceParam param) {
        int total = supplyCardDao.querySupplyCardBalanceCount(param);
        param.getPageUnit().setTotal(total);
        if (total == 0) {
            param.getPageUnit().setResultList(new ArrayList<>());
        } else {
            param.getPageUnit().setResultList(supplyCardDao.querySupplyCardBalancePage(param));
        }
        return param.getPageUnit();
    }

    /**
     * 会员销卡明细导出
     *
     * @param param
     * @param response
     * @return
     */
    @Override
    public void supplyCardDetailDownLoad(SupplyCardDetailParam param, HttpServletResponse response) {
        int total = supplyCardDao.querySupplyCardDetailCount(param);
        BufferedWriter bufferedWriter = null;
        try {
            ServletOutputStream servletOutputStream = response.getOutputStream();
            response.setHeader("Content-disposition", "attachment;filename=" + System.currentTimeMillis() + ".csv");
            Page page = new Page();
            page.setSize(5000);
            page.setTotal(total);
            param.setPageUnit(page);
            bufferedWriter = new BufferedWriter(new OutputStreamWriter(servletOutputStream, "GBK"));
            bufferedWriter.write("订单号,批次号,卡号,运营商类型,开始时间,会员编号,会员名称,消费类型,结算金额,剩余供卡余额");
            bufferedWriter.newLine();
            while (page.getPage() <= page.getMaxPage()) {
                List<SupplyCardDetailDto> list = supplyCardDao.querySupplyCardDetailPage(param);
                list.forEach((bean) -> {
                    SupplyProduct product;
                    if (bean.getProductId() != null&&bean.getProductId()!=0) {
                        product = collectCardRecordDao.queryProductInfoById(bean.getProductId());
                    } else {
                        product = collectCardRecordDao.queryProductInfoByFaceAreaType(bean.getFace(), bean.getArea(), bean.getProductType());
                    }
                    if (product != null) {
                        bean.setCardOperatorName(product.getCardOperatorName());
                    }
                });
                int size = list.size();
                StringBuffer data = new StringBuffer(size * 100);
                for (int i = 0; i < size; i++) {
                    data.append(list.get(i));
                }
                bufferedWriter.write(StringUtils.replace(data.toString(), "null", ""));
                page.setPage(page.getPage() + 1);
            }
            bufferedWriter.flush();
        } catch (Exception e) {
            log.warn("供货日报表导出出错", e);
        } finally {
            IOUtils.closeQuietly(bufferedWriter);
        }
    }

    /**
     * 会员销卡明细导出
     *
     * @param param
     * @param response
     * @return
     */
    @Override
    public void supplyCardBalanceDownLoad(SupplyCardBalanceParam param, HttpServletResponse response) {
        int total = supplyCardDao.querySupplyCardBalanceCount(param);
        BufferedWriter bufferedWriter = null;
        try {
            ServletOutputStream servletOutputStream = response.getOutputStream();
            response.setHeader("Content-disposition", "attachment;filename=" + System.currentTimeMillis() + ".csv");
            Page page = new Page();
            page.setSize(5000);
            page.setTotal(total);
            param.setPageUnit(page);
            bufferedWriter = new BufferedWriter(new OutputStreamWriter(servletOutputStream, "GBK"));
            bufferedWriter.write("会员编号,会员名称,会员状态,产品经理,可提现金额,提现状态");
            bufferedWriter.newLine();
            while (page.getPage() <= page.getMaxPage()) {
                List<SupplyCardBalanceDto> list = supplyCardDao.querySupplyCardBalancePage(param);
                int size = list.size();
                StringBuffer data = new StringBuffer(size * 100);
                for (int i = 0; i < size; i++) {
                    data.append(list.get(i));
                }
                bufferedWriter.write(StringUtils.replace(data.toString(), "null", ""));
                page.setPage(page.getPage() + 1);
            }
            bufferedWriter.flush();
        } catch (Exception e) {
            log.warn("会员销卡余额导出出错", e);
        } finally {
            IOUtils.closeQuietly(bufferedWriter);
        }
    }

    /**
     * 收卡批量返佣
     *
     * @param data    源数据
     * @param addType 加款类型
     * @return MessageBean
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public MessageBean newBatchSubmitUserAddMoneyApply(String data, UserAddMoneyTypeEnum addType) {
        MultiResult<MessageBean, StringBuffer> dataPreCheck = financeUtils.dataPreCheck(data);
        MessageBean failReason = dataPreCheck.getLeft();
        if (failReason != null) {
            return failReason;
        }
        StringBuffer right = dataPreCheck.getRight();
        final long time = System.currentTimeMillis();
        final String orderId = time + "R";
        Arrays.stream(right.toString().split(";")).forEach(singleData -> {
            String[] info = singleData.split(",");
            SupUser userFromDb = userDao.querySupUsersByAccount(info[0]);
            if ((addType == UserAddMoneyTypeEnum.RAKEBACK) && (supplyCardDao.queryRebateRecord(userFromDb.getUserId()) != null)) {
                throw new OperateFailException(info[0] + ",24小时内操作过返点");
            }
            BigDecimal rebate = new BigDecimal(info[1]);
            SupplyConsumption supplyConsumption =
                    new SupplyConsumption(userFromDb.getUserId(), addType.getSupBalanceCgStatus(), userFromDb.getUserId() + orderId,
                            addType.getMsg(), rebate, 0);
            supplyFinanceService.modifyBalanceConsumption(supplyConsumption);

        });
        return MessageBean.success();
    }


}
